﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using LetiLib.Utils;

namespace LetiLib.FontData
{
    public class ElementsMap
    {
    public struct ElementKey
        {
            public string Name;
            public byte Size;
        }

        private List<JsonCustomElement> jsonElementsMap;
        private static ElementsMap _instance;
        private static object lockObj = new object();
        private Dictionary<ElementKey, CustomElement> elementsMap = new Dictionary<ElementKey, CustomElement>();
        public List<JsonCustomElement> Map
        {
            get { return jsonElementsMap; }
            
        }
        public ElementsMap()
        {
            string strCharMapContent = Resource.ElementsMap;
            jsonElementsMap = JSONHelper.Deserialise<List<JsonCustomElement>>(strCharMapContent);
        }

        public static ElementsMap Instance()
        {
            lock (lockObj)
            {
                if (_instance == null)
                {
                    _instance = new ElementsMap();
                }
            }

            return _instance;
        }

        public CustomElement GetElement(string name, byte size = 8)
        {
            lock (lockObj)
            {
                if (!elementsMap.Keys.Any(p => p.Name.Equals(name) && p.Size == size))
                {
                    JsonCustomElement jsonElement = jsonElementsMap.Where(p => name.Equals(p.Name) && p.Size == size).FirstOrDefault();
                    if (jsonElement != null)
                    {
                        ElementKey newKey = new ElementKey();
                        newKey.Name = jsonElement.Name;
                        newKey.Size = jsonElement.Size;
                        elementsMap.Add(newKey, jsonElement.GetCustomElement());
                    }
                }
            }

            return elementsMap.Where(p => (p.Key.Name.Equals(name) && p.Key.Size == size)).FirstOrDefault().Value;
        }
    }

    [DataContract]
    public class JsonCustomElement
    {
        [DataMember]
        public string Name;
        [DataMember]
        public byte Size;
        [DataMember]
        public byte Height;
        [DataMember]
        public byte Width;
        [DataMember]
        public byte[] Points;

        public JsonCustomElement() { }

        public CustomElement GetCustomElement()
        {
            return new CustomElement()
            {
                Height = this.Height,
                Width = this.Width,
                Mask = GetPointList().ToList<Point>()
            };
        }

        private IEnumerable<Point> GetPointList()
        {
            if (Points != null)
                for (int i = 0; i < Points.Length; i = i + 2)
                {
                    yield return new Point(Points[i], Points[i + 1]);
                }
        }
    }
}
